<?php
/**
 * Image manipulation class
 *
 * @author André Silva
 */
class Image {
	/**
	 * @var string
	 */
	protected $image;
	/**
	 * @var string
	 */
	protected $extension;
	/**
	 * @var integer
	 */
	protected $width;
	/**
	 * @var integer
	 */
	protected $height;
	/**
	 * @var string
	 */
	protected $type;
	/**
	 * @var string
	 */
	protected $mimeType;
	
	protected $allowedTypes = array(
			'image/pjpeg'=>'jpg',
			'image/jpeg'=>'jpg',
			'image/jpg'=>'jpg',
			'image/png'=>'png',
			'image/x-png'=>'png',
			'image/gif'=>'gif'
	);

	/**
	 * Create a new image object
	 * @param string $image
	 */
	public function __construct($image) {
		if(!file_exists($image)) {
			throw new Exception('Invalid image: no file found ('.basename($this->image).')');
		}
		if(is_dir($image)) {
			throw new Exception('Invalid image: can\'t be a folder ('.basename($this->image).')');
		}

		$this->image = $image;
		list($this->width, $this->height, $this->type) = getimagesize($image);
		$this->mimeType = image_type_to_mime_type($this->type);

		preg_match("/\.(gif|png|jpg|jpeg){1}$/i", $image, $ext);
		$this->extension = end($ext);

		if(!array_key_exists($this->mimeType, $this->allowedTypes)) {
			throw new Exception('Invalid image type: '.$this->mimeType.' ('.basename($this->image).')');
		}
	}

	/**
	 * Build the full path for the given folder
	 * @param string $folder
	 */
	private function checkFolder($folder) {
		if(!file_exists($folder)) {
			mkdir($folder, 0755, true);
		}
	}

	/**
	 * Copy the current image to a new path
	 * @param string $file
	 */
	public function copy($file) {
		$this->checkFolder(dirname($file));
		if(!copy($this->image, $file)) {
			throw new Exception('Error while copying image '.basename($this->image).' to '.basename($file));
		}
	}

	/**
	 * Resize the current image
	 * @param integer $width
	 * @param integer $height
	 * @param integer $thumb Resized image
	 */
	public function resizeImage($width, $height, $thumb = null) {
		if($thumb == null) {
			$thumb = $this->image;
		}
		$newImage = imagecreatetruecolor($width,$height);
		switch($this->mimeType) {
			case "image/gif":
				$source=imagecreatefromgif($this->image);
				break;
			case "image/pjpeg":
			case "image/jpeg":
			case "image/jpg":
				$source=imagecreatefromjpeg($this->image);
				break;
			case "image/png":
			case "image/x-png":
				$source=imagecreatefrompng($this->image);
				break;
		}
		imagecopyresampled($newImage,$source,0,0,0,0,$width,$height,$this->width,$this->height);

		switch($this->mimeType) {
			case "image/gif":
				imagegif($newImage,$thumb);
				break;
			case "image/pjpeg":
			case "image/jpeg":
			case "image/jpg":
				imagejpeg($newImage,$thumb,90);
				break;
			case "image/png":
			case "image/x-png":
				imagepng($newImage,$thumb,90);
				break;
		}

		chmod($thumb, 0755);
	}

	/**
	 * Create a thumbnail of the current image
	 * @param string $thumb Thumbnail path
	 * @param integer $x
	 * @param integer $y
	 * @param integer $width
	 * @param integer $height
	 * @param float $scale
	 */
	public function resizeThumbnailImage($thumb, $x, $y, $width, $height, $scale) {
		$this->checkFolder(dirname($thumb));
		$newWidth = ceil($width * $scale);
		$newHeight = ceil($height * $scale);
		$newImage = imagecreatetruecolor($newWidth,$newHeight);
		switch($this->mimeType) {
			case "image/gif":
				$source=imagecreatefromgif($this->image);
				break;
			case "image/pjpeg":
			case "image/jpeg":
			case "image/jpg":
				$source=imagecreatefromjpeg($this->image);
				break;
			case "image/png":
			case "image/x-png":
				$source=imagecreatefrompng($this->image);
				break;
		}
		imagecopyresampled($newImage,$source,0,0,$x,$y,$newWidth,$newHeight,$width,$height);
		switch($this->mimeType) {
			case "image/gif":
				imagegif($newImage,$thumb);
				break;
			case "image/pjpeg":
			case "image/jpeg":
			case "image/jpg":
				imagejpeg($newImage,$thumb,90);
				break;
			case "image/png":
			case "image/x-png":
				imagepng($newImage,$thumb,90);
				break;
		}
		chmod($thumb, 0755);
	}

	/**
	 * @return string
	 */
	public function getImage() {
		return $this->image;
	}

	/**
	 * @return string
	 */
	public function getExtension() {
		return $this->extension;
	}

	/**
	 * @return integer
	 */
	public function getWidth() {
		return $this->width;
	}

	/**
	 * @return integer
	 */
	public function getHeight() {
		return $this->height;
	}

	/**
	 * @return string
	 */
	public function getType() {
		return $this->type;
	}

	/**
	 * @return string
	 */
	public function getMimeType() {
		return $this->mimeType;
	}
}
?>
